//编程实现字符串的循环右移
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

/**
    开辟一个缓冲区
        假设要移动位数n，那么实际上移动的位数 n%len
        也就是从str[len-位数+1]开始到最后这些字符，放入缓存区
        将str的0到len-位数，这几个字符，整体向后移动n位
        再将缓存区的填到字符串前面去

*/
//使用string容器
string LoopMove_1(string s,int n)
{
    if(n<0)
    {
        printf("参数错误");
        exit(0);
    }
    if(n==0 || s.length()==0 || n==s.length())
    {
        return s;
    }

    int len = s.length();
    n = n%len;
    char tmp[n]; //缓存区

    //最后的字符存到缓存区
    for(int i = len-n,j = 0;i<len;i++,j++)
    {
        tmp[j] = s[i];
    }

    //字符串移动
    for(int i =len-n-1, j=len-1;i>=0;i--,j--)
    {
        s[j]=s[i];
    }

    //将缓存区添加到字符串前面
    for(int i =0;i<n;i++)
    {
        s[i]=tmp[i];
    }
    return s;
}

//使用C风格字符串
int LoopMove_2(char * str,int n)
{
    if(n<0||str==NULL)
    {
        printf("参数错误");
        exit(0);
    }

    int len = strlen(str);
    n = n%len;

    //缓存
    char * tmp = (char *)malloc((n+1)*sizeof(char));
    tmp[n]='\0';



    //将字符串n位移动到缓存中
    for(int i = len-n,j=0;i<len;i++,j++)
    {
        tmp[j]=str[i];
    }

    //移动字符串
    for(int i = len-n-1,j=len-1;i>=0;i--,j--)
    {
        str[j]=str[i];
    }
    //将缓存的字符填回去
    for(int i=0;i<n;i++)
    {
        str[i]=tmp[i];
    }
    return 1;
}
/**
    实际上还有一种优化的方式，比如n>len/2的时候，其实可以左移
*/
int main()
{
    string s;
    cout<<"输入字符串"<<endl;
    getline(cin,s);
    cout<<"循环移动后："<<LoopMove_1(s,3)<<endl;
    cout<<"输入字符串"<<endl;
    getline(cin,s);
    char * str = (char *)malloc((s.length()+1)*sizeof(char));
    for(int i = 0;i<s.length();i++)
    {
        str[i]=s[i];
    }
    str[s.length()]='\0';
    LoopMove_2(str,3);
    cout<<"循环移动后："<<str<<endl;
    system("pause");
    return 0;
}
